package Optimizer;

import Engine.src.ca.uqac.dim.turtledb.*;
import Engine.src.ca.uqac.dim.turtledb.util.*;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Map;

public class Exemple {
	
    public static void main(String[] args){
        // Query Translator
        String query = "SELECT Astronaut.Name, Astronaut.Nationality FROM Astronaut, Crew WHERE Astronaut.Name=Crew.Astronaut AND (Crew.Mission='Gemini VII' OR Crew.Mission='Apollo 7');";
        Relation arbre = QueryTranslator.translate(query);
        System.out.println(XmlQueryFormatter.toXmlString(arbre));
        System.out.println(GraphvizQueryFormatter.toGraphviz(arbre));
               
        // Load tables from files
        Relation r_Astronaut = null, r_Mission = null, r_Crew = null, r_Rocket = null;

        try{
            r_Astronaut = XmlQueryParser.parse(FileReadWrite.getFileContents("data/Space/Astronaut.xml"));
            r_Mission = XmlQueryParser.parse(FileReadWrite.getFileContents("data/Space/Mission.xml"));
            r_Crew = XmlQueryParser.parse(FileReadWrite.getFileContents("data/Space/Crew.xml"));
            r_Rocket = XmlQueryParser.parse(FileReadWrite.getFileContents("data/Space/Rocket.xml"));
        }
        catch (FileNotFoundException e){
            System.err.println("File not found");
            System.exit(1);
        }
        catch (IOException e){
            System.err.println("Error reading files");
            System.exit(1);
        }
        catch (XmlQueryParser.ParseException e){
        System.err.println("Error parsing XML files");
        System.exit(1);
        }
        if (r_Astronaut == null || r_Mission == null || r_Crew == null || r_Rocket == null){
            System.err.println("Error reading Space database");
            System.exit(1);
        }
                
        // Initialisation optimizer avec toutes les informations de base
        QueryOptimizer optimizer = new QueryOptimizer();
        optimizer.addSite("Site 1");
        optimizer.addSite("Site 2");
        optimizer.addSite("Site 3"); // supercalculateur ne contient jamais de table
        optimizer.setCoutCommunication("Site 1", "Site 2", 20);
        optimizer.setCoutCommunication("Site 1", "Site 3", 1);
        optimizer.setCoutCommunication("Site 2", "Site 3", 2);
        optimizer.setCoutStockageSite("Site 1", 10);
        optimizer.setCoutStockageSite("Site 2", 10);
        optimizer.setCoutStockageSite("Site 3", 10);
        optimizer.setAllocationFragmentSite("F1", "Site 2");
        optimizer.setAllocationFragmentSite("F2", "Site 1");
        // optimizer.setAllocationFragmentSite("F3", "Site 2");
        // optimizer.setAllocationFragmentSite("F4", "Site 1");
        optimizer.setAllocationFragmentSite("F5", "Site 3");
        optimizer.addFragment("F1", r_Astronaut);
        optimizer.addFragment("F2", r_Crew);
        // optimizer.addFragment("F3", r_Mission);
        // optimizer.addFragment("F4", r_Rocket);
        // optimizer.addFragment("F5", prod);

        QueryPlan qp = optimizer.optimizeQuery(arbre);
        System.out.println("Coût du plan de requête : "+optimizer.getCost(qp));
        
        // Instantiates the centralized communication manager
        CentralizedCommunicator cm = new CentralizedCommunicator();
        
        // Populate site 1
        for(Map.Entry<String, Relation> entry : optimizer.getFragments().entrySet()){
            Engine site = new Engine(optimizer.getAllocationFragmentSite(entry.getKey()));
            site.putRelation(entry.getKey(), entry.getValue());
            cm.addSite(site);
        }
        
        cm.run();
        
        // Have the communicator execute the plan
        QueryProcessor p = cm.getQueryProcessor(qp);
        p.run();
        Relation result = p.getResult();
        System.out.println(result);  
    }
}